package com.akaovi.shareWare.gui;

import com.akaovi.shareWare.client.Client;
import com.akaovi.shareWare.mess.TextMess;
import com.akaovi.shareWare.server.Server;
import com.akaovi.shareWare.utils.Utils;

import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.event.*;
import java.net.InetAddress;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author akaovi
 * @version 1.0
 * @description
 * @date 2022/10/13 23:23
 * @since 2022/10/13 23:23
 */
public class ShareWareGui extends JFrame {

    private Server server = null;
    private Client client = null;
    private InetAddress targetIp = null;
    Font font = new Font(null, Font.BOLD, 16);
    private final ThreadPoolExecutor threadPool;

    // 组件
    private JLabel textShareInputLabel;  // 文本同步标签
    private JTextArea textShareInputArea;  // 文本同步输入框
    private JButton textShareInputCommitButton;  // 文本同步提交按钮
    private JLabel showTextAreaLabel;  // 文本同步展示标签
    private JTextArea showTextArea;  // 文本同步展示框
    private JButton showTextAreaUpdate;  // 拉取更新按钮
    private JLabel textOrderNumLabel;  // 文本序号标签
    private JTextField textOrderNumFiled;  // 文本序号填写框
    private JButton copyButton;  // 点击复制按钮
    private JLabel targetIpAddrLabel;  // 目标ip标签
    private JTextField targetIpAddrField;  // 目标ip填写框
    private JLabel statusLabel;  // 状态标签
    private JButton updateIpAddrButton;  // 修改ip按钮
    private JButton conformIpAddrButton;  // 确认ip按钮
    private JLabel filePathLabel;  // 文件路径标签
    private JTextArea filePathTextArea;  // 文件路径框
    private JButton filePathChooseButton; // 文件路径选择按钮
    private JButton sendFileButton;  // 发送选中文件按钮
    private JLabel receiveFuncLabel;  // 是否开启接收功能标签
    private JButton openReceiveFuncButton;  // 开启接收功能按钮
    private JButton closeReceiveFuncButton;  // 关闭接收功能按钮
    private JLabel refuseAllFilesLabel;  // 绝收文件模式标签
    private JButton openRefuseAllFilesButton;  // 开启绝收文件模式按钮
    private JButton closeRefuseAllFilesButton;  // 关闭绝收文件模式按钮

    private JLabel pullFileLabel;  // 拉去文件标签

    private JButton pullFileButton;  // 拉去文件按钮

    public ShareWareGui() {
        this.threadPool = new ThreadPoolExecutor(Utils.getCorePoolSize(), Utils.getMaxPoolSize(), 1, TimeUnit.MINUTES, new LinkedBlockingQueue<>());
        this.setLayout(null);
        JLabel jb = new JLabel();
        setTitle("SharedBox");//窗口标题
        this.setBounds(200, 100, 800, 600); // 设置大小
        this.setLocationRelativeTo(null);  // 屏幕正中间

        setResizable(false);// 设置窗体是否可以调整大小，参数为布尔值
        this.add(jb);//将其加入到窗口当中

        Toolkit kit = Toolkit.getDefaultToolkit();
        Image image = kit.getImage("src//image//0x1f4dd.png"); //设置窗口图标路径
        setIconImage(image); //换掉窗体样式

        // 添加各种组件
        addTextShareInputLabel();
        addTextShareInput();
        addTextShareInputButton();
        addShowTextAreaLabel();
        addShowTextArea();
        addPullUpdateButton();
        addTextOrderNumLabel();
        addTextOrderNumFiled();
        addCopyButton();
        addTargetIpAddrLabel();
        addTargetIpAddrField();
        addStatusLabel();
        addUpdateIpAddrButton();
        addConformIpAddrButton();
        bindListenerForUpdateIpAddrButton();
        addFilePathLabel();
        addFilePathTextArea();
        addFilePathChooseButton();
        addSendFileButton();
        addReceiveFuncLabel();
        addOpenReceiveFuncButton();
        addCloseReceiveFuncButton();
        bindListenerForOpenReceiveFuncButton();
        bindListenerForTextShareInputCommitButton();
        bindListenerForShowTextAreaUpdate();
        bindListenerForCopyButton();
        addRefuseAllFilesLabel();
        addOpenRefuseAllFilesButton();
        addCloseRefuseAllFilesButton();
        bindListenerForOpenRefuseAllFilesButton();
        addPullFileLabel();
        addPullFileButton();

        // 收尾
        setDefaultCloseOperation(EXIT_ON_CLOSE);// 用户点击窗口关闭
        this.setVisible(true);//设置是否窗口显示

        addWindowListener(new WindowListener() {
            @Override
            public void windowOpened(WindowEvent e) {

            }

            @Override
            public void windowClosing(WindowEvent e) {
                try {
                    threadPool.shutdown();
                } catch (Exception exception) {
                    exception.printStackTrace();
                }
            }

            @Override
            public void windowClosed(WindowEvent e) {

            }

            @Override
            public void windowIconified(WindowEvent e) {

            }

            @Override
            public void windowDeiconified(WindowEvent e) {

            }

            @Override
            public void windowActivated(WindowEvent e) {

            }

            @Override
            public void windowDeactivated(WindowEvent e) {

            }
        });
    }

    private void addTextShareInputLabel() {
        textShareInputLabel = new JLabel("文本同步:");
        textShareInputLabel.setBounds(10, 20, 100, 25);
        textShareInputLabel.setFont(font);
        this.add(textShareInputLabel);
    }

    private void addTextShareInput() {
        textShareInputArea = new JTextArea();
        textShareInputArea.setBounds(110, 20, 300, 100);
        textShareInputArea.setLineWrap(true);
        this.add(textShareInputArea);
    }


    private void addTextShareInputButton() {
        textShareInputCommitButton = new JButton("提交");
        textShareInputCommitButton.setFont(font);
        textShareInputCommitButton.setFocusPainted(false);
        textShareInputCommitButton.setBounds(420, 20, 70, 25);
        this.add(textShareInputCommitButton);
    }

    private void addShowTextAreaLabel() {
        showTextAreaLabel = new JLabel("文本同步:");
        showTextAreaLabel.setBounds(10, 130, 100, 25);
        showTextAreaLabel.setFont(font);
        this.add(showTextAreaLabel);
    }

    private void addShowTextArea() {
        showTextArea = new JTextArea();
        showTextArea.setBounds(110, 130, 300, 350);
        showTextArea.setLineWrap(true);
        showTextArea.setEditable(false);
        this.add(showTextArea);
    }

    private void addPullUpdateButton() {
        showTextAreaUpdate = new JButton("更新");
        showTextAreaUpdate.setFont(font);
        showTextAreaUpdate.setFocusPainted(false);
        showTextAreaUpdate.setBounds(420, 130, 70, 25);
        this.add(showTextAreaUpdate);
    }

    private void addTextOrderNumLabel() {
        textOrderNumLabel = new JLabel("待复制文本序号: ");
        textOrderNumLabel.setBounds(10, 490, 150, 25);
        textOrderNumLabel.setFont(font);
        this.add(textOrderNumLabel);
    }

    private void addTextOrderNumFiled() {
        textOrderNumFiled = new JTextField();
        textOrderNumFiled.setBounds(160, 490, 50, 25);
        this.add(textOrderNumFiled);
    }

    private void addCopyButton() {
        copyButton = new JButton("点击复制");
        copyButton.setFont(font);
        copyButton.setFocusPainted(false);
        copyButton.setBounds(230, 490, 100, 25);
        this.add(copyButton);
    }

    private void addTargetIpAddrLabel() {
        targetIpAddrLabel = new JLabel("连接到IP(IPv4): ");
        targetIpAddrLabel.setFont(font);
        targetIpAddrLabel.setBounds(190, 520, 120, 25);
        this.add(targetIpAddrLabel);
    }

    private void addTargetIpAddrField() {
        targetIpAddrField = new JTextField();
        targetIpAddrField.setBounds(320, 520, 100, 25);
        targetIpAddrField.addKeyListener(new KeyListener() {
            @Override
            public void keyTyped(KeyEvent e) {

            }

            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == 10) {
                    conformIpAddrButton.doClick();
                }
            }

            @Override
            public void keyReleased(KeyEvent e) {

            }
        });
        this.add(targetIpAddrField);
    }

    private void addStatusLabel() {
        statusLabel = new JLabel();
        statusLabel.setBounds(500, 230, 170, 25);
        statusLabel.setFont(font);
        statusLabel.setVisible(false);
        this.add(statusLabel);
    }

    private void addUpdateIpAddrButton() {
        updateIpAddrButton = new JButton("修改");
        updateIpAddrButton.setFont(font);
        updateIpAddrButton.setFocusPainted(false);
        updateIpAddrButton.setBounds(430, 520, 70, 25);
        updateIpAddrButton.setEnabled(false);
        this.add(updateIpAddrButton);
    }

    private void addConformIpAddrButton() {
        conformIpAddrButton = new JButton("确认");
        conformIpAddrButton.setFont(font);
        conformIpAddrButton.setFocusPainted(false);
        conformIpAddrButton.setBounds(520, 520, 70, 25);
        conformIpAddrButton.addActionListener(e -> {
            // 校验
            if ("".equals(targetIpAddrField.getText())) {
                JOptionPane.showMessageDialog(
                        null,
                        "IP不能为空",
                        "警告",
                        JOptionPane.WARNING_MESSAGE);
            } else {
                InetAddress ip = Utils.getIpAddress(targetIpAddrField.getText());
                if (ip == null) {
                    JOptionPane.showMessageDialog(
                            null,
                            "ip填写有误",
                            "警告",
                            JOptionPane.WARNING_MESSAGE);
                } else {
                    statusLabel.setText("连接到: " + targetIpAddrField.getText());
                    statusLabel.setVisible(true);
                    updateIpAddrButton.setEnabled(true);
                    targetIpAddrField.setEditable(false);
                    conformIpAddrButton.setEnabled(false);
                    this.targetIp = ip;
                    if (client == null) {
                        this.client = new Client(this.targetIp);
                    } else if (client.getTargetAddr() != this.targetIp) {
                        this.client.setTargetAddr(this.targetIp);
                    }
                    JOptionPane.showMessageDialog(
                            null,
                            "连接到: " + targetIpAddrField.getText(),
                            "提示",
                            JOptionPane.INFORMATION_MESSAGE);
                }
            }
        });
        this.add(conformIpAddrButton);
    }

    private void bindListenerForUpdateIpAddrButton() {
        updateIpAddrButton.addActionListener(e -> {
            conformIpAddrButton.setEnabled(true);
            targetIpAddrField.setEditable(true);
            updateIpAddrButton.setEnabled(false);
        });
    }

    private void addFilePathLabel() {
        filePathLabel = new JLabel("文件路径 ");
        filePathLabel.setBounds(500, 20, 100, 25);
        filePathLabel.setFont(font);
        this.add(filePathLabel);
    }

    private void addFilePathTextArea() {
        filePathTextArea = new JTextArea();
        filePathTextArea.setBounds(500, 50, 250, 100);
        filePathTextArea.setFont(new Font(null, Font.PLAIN, 18));
        filePathTextArea.setLineWrap(true);
        filePathTextArea.setEditable(false);
        this.add(filePathTextArea);
    }

    private void addFilePathChooseButton() {
        filePathChooseButton = new JButton("选择文件");
        filePathChooseButton.setBounds(500, 160, 100, 25);
        filePathChooseButton.setFocusPainted(false);
        filePathChooseButton.setFont(font);
        filePathChooseButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                //按钮点击事件
                JFileChooser chooser = new JFileChooser();             //设置选择器
                int returnVal = chooser.showOpenDialog(filePathChooseButton);        //是否打开文件选择框
                if (returnVal == JFileChooser.APPROVE_OPTION) {          //如果符合文件类型
                    String filepath = chooser.getSelectedFile().getAbsolutePath();      //获取绝对路径
                    filePathTextArea.setText(filepath);
                }
            }
        });
        this.add(filePathChooseButton);
    }

    private void addSendFileButton() {
        sendFileButton = new JButton("发送文件");
        sendFileButton.setBounds(650, 160, 100, 25);
        sendFileButton.setFont(font);
        sendFileButton.setFocusPainted(false);
        sendFileButton.addActionListener(e -> {
            if ("".equals(filePathTextArea.getText())) {
                JOptionPane.showMessageDialog(
                        null,
                        "无文件被选中",
                        "警告",
                        JOptionPane.WARNING_MESSAGE);
            } else if (targetIpAddrField.isEditable()) {
                JOptionPane.showMessageDialog(
                        null,
                        "IP正处于修改状态，不可发送",
                        "警告",
                        JOptionPane.WARNING_MESSAGE);
            } else {
                int res = JOptionPane.showConfirmDialog(
                        null,
                        "确认发送",
                        "提示",
                        JOptionPane.YES_NO_CANCEL_OPTION);
                if (res == 0) {
                    threadPool.execute(() -> {
                        if (client == null) {
                            this.client = new Client(this.targetIp);
                        } else if (client.getTargetAddr() != this.targetIp) {
                            this.client.setTargetAddr(this.targetIp);
                        }
                        // 发送文件
                        String filePath = filePathTextArea.getText().replace("\\", "/");
                        client.sendToShareFile(Utils.getFileMess(filePath), filePath);
                    });
                }
            }

        });
        this.add(sendFileButton);
    }

    private void addReceiveFuncLabel() {
        receiveFuncLabel = new JLabel("接收功能:");
        receiveFuncLabel.setBounds(500, 200, 80, 25);
        receiveFuncLabel.setFont(font);
        this.add(receiveFuncLabel);
    }

    private void addOpenReceiveFuncButton() {
        openReceiveFuncButton = new JButton("开");
        openReceiveFuncButton.setFocusPainted(false);
        openReceiveFuncButton.setFont(font);
        openReceiveFuncButton.setBounds(590, 200, 60, 25);
        this.add(openReceiveFuncButton);
    }

    private void addCloseReceiveFuncButton() {
        closeReceiveFuncButton = new JButton("关");
        closeReceiveFuncButton.setEnabled(false);
        closeReceiveFuncButton.setFocusPainted(false);
        closeReceiveFuncButton.setFont(font);
        closeReceiveFuncButton.setBounds(660, 200, 60, 25);
        closeReceiveFuncButton.addActionListener(e -> {
            if (server != null) {
                server.closeListen();
                JOptionPane.showMessageDialog(
                        null,
                        "接收功能关闭啦",
                        "提示",
                        JOptionPane.INFORMATION_MESSAGE);
                closeReceiveFuncButton.setEnabled(false);
                openReceiveFuncButton.setEnabled(true);
            } else {
                JOptionPane.showMessageDialog(
                        null,
                        "你他妈的没开启接收功能",
                        "警告",
                        JOptionPane.WARNING_MESSAGE);
            }
        });
        this.add(closeReceiveFuncButton);
    }

    private void bindListenerForOpenReceiveFuncButton() {
        openReceiveFuncButton.addActionListener(e -> {
            // 开启
            threadPool.execute(() -> {
                if (server == null) {
                    this.server = new Server(threadPool);
                }
                this.server.openListen();
            });
            openReceiveFuncButton.setEnabled(false);
            closeReceiveFuncButton.setEnabled(true);
            JOptionPane.showMessageDialog(
                    null,
                    "接收功能开启啦",
                    "提示",
                    JOptionPane.INFORMATION_MESSAGE);

        });
    }

    private void bindListenerForTextShareInputCommitButton() {
        textShareInputCommitButton.addActionListener(e -> {
            if ("".equals(textShareInputArea.getText())) {
                JOptionPane.showMessageDialog(
                        null,
                        "不能发送空字符串",
                        "警告",
                        JOptionPane.WARNING_MESSAGE);
            } else if (targetIpAddrField.isEditable()) {
                JOptionPane.showMessageDialog(
                        null,
                        "IP正处于修改状态，不可发送",
                        "警告",
                        JOptionPane.WARNING_MESSAGE);
            } else {
                int res = JOptionPane.showConfirmDialog(
                        null,
                        "确认发送",
                        "提示",
                        JOptionPane.YES_NO_CANCEL_OPTION);
                if (res == 0) {
                    // 发送
                    threadPool.execute(() -> {
                        if (client == null) {
                            this.client = new Client(this.targetIp);
                        } else if (client.getTargetAddr() != this.targetIp) {
                            this.client.setTargetAddr(this.targetIp);
                        }
                        // 发送文本
                        TextMess mess = Utils.getTextMess(textShareInputArea.getText());
                        client.sendToShareText(mess);
                    });
                }
            }
        });
    }

    private void bindListenerForShowTextAreaUpdate() {
        showTextAreaUpdate.addActionListener(e -> {
            if (targetIpAddrField.isEditable()) {
                JOptionPane.showMessageDialog(
                        null,
                        "IP正处于修改状态，无法更新",
                        "警告",
                        JOptionPane.WARNING_MESSAGE);
            } else {
                int res = JOptionPane.showConfirmDialog(
                        null,
                        "是否更新",
                        "提示",
                        JOptionPane.YES_NO_CANCEL_OPTION);
                if (res == 0) {
                    try {
                        threadPool.execute(() -> {
                            showTextArea.setText(client.sendToGetTextShared(Utils.getCacheMess(null)));
                        });
                    } catch (Exception exception) {
                        JOptionPane.showMessageDialog(
                                null,
                                "对方未开启服务",
                                "提示",
                                JOptionPane.INFORMATION_MESSAGE);
                    }

                }
            }
        });
    }

    private void bindListenerForCopyButton() {
        copyButton.addActionListener(e -> {
            if ("".equals(showTextArea.getText())) {
                JOptionPane.showMessageDialog(
                        null,
                        "展示框无内容",
                        "警告",
                        JOptionPane.WARNING_MESSAGE);
            } else if ("".equals(textOrderNumFiled.getText())) {
                JOptionPane.showMessageDialog(
                        null,
                        "请填写待复制内容的序号",
                        "警告",
                        JOptionPane.WARNING_MESSAGE);
            } else {
                if (Utils.isIllegal(textOrderNumFiled.getText())) {
                    String text = client.getCache().getDetails(textOrderNumFiled.getText().trim());
                    // 获取系统剪贴板
                    Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
                    // 封装文本内容
                    Transferable trans = new StringSelection(text);
                    // 把文本内容设置到系统剪贴板
                    clipboard.setContents(trans, null);
                    JOptionPane.showMessageDialog(
                            null,
                            "复制成功",
                            "提示",
                            JOptionPane.INFORMATION_MESSAGE);
                } else {
                    JOptionPane.showMessageDialog(
                            null,
                            "不合法的输入",
                            "警告",
                            JOptionPane.WARNING_MESSAGE);
                }

            }
        });
    }

    private void addRefuseAllFilesLabel() {
        refuseAllFilesLabel = new JLabel("拒接文件:");
        refuseAllFilesLabel.setBounds(500, 260, 80, 25);
        refuseAllFilesLabel.setFont(font);
        this.add(refuseAllFilesLabel);
    }

    private void addOpenRefuseAllFilesButton() {
        openRefuseAllFilesButton = new JButton("开");
        openRefuseAllFilesButton.setFocusPainted(false);
        openRefuseAllFilesButton.setFont(font);
        openRefuseAllFilesButton.setBounds(590, 260, 60, 25);
        this.add(openRefuseAllFilesButton);
    }

    private void addCloseRefuseAllFilesButton() {
        closeRefuseAllFilesButton = new JButton("关");
        closeRefuseAllFilesButton.setEnabled(false);
        closeRefuseAllFilesButton.setFocusPainted(false);
        closeRefuseAllFilesButton.setFont(font);
        closeRefuseAllFilesButton.setBounds(660, 260, 60, 25);
        closeRefuseAllFilesButton.addActionListener(e -> {
            this.server.closeRefuseFileMode();
            openRefuseAllFilesButton.setEnabled(true);
            closeRefuseAllFilesButton.setEnabled(false);
            JOptionPane.showMessageDialog(
                    null,
                    "拒接文件模式已关闭",
                    "提示",
                    JOptionPane.INFORMATION_MESSAGE);
        });
        this.add(closeRefuseAllFilesButton);
    }

    private void bindListenerForOpenRefuseAllFilesButton() {
        openRefuseAllFilesButton.addActionListener(e -> {
            if (closeReceiveFuncButton.isEnabled()) {
                int res = JOptionPane.showConfirmDialog(
                        null,
                        "确认是否开启拒收文件模式，拒收文件，并不再提醒",
                        "拒收文件",
                        JOptionPane.YES_NO_CANCEL_OPTION);
                if (res == 0) {
                    this.server.openRefuseFileMode();
                    openRefuseAllFilesButton.setEnabled(false);
                    closeRefuseAllFilesButton.setEnabled(true);
                    JOptionPane.showMessageDialog(
                            null,
                            "拒接文件模式已开启",
                            "提示",
                            JOptionPane.INFORMATION_MESSAGE);
                }
            } else {
                JOptionPane.showMessageDialog(
                        null,
                        "请先开启接收服务",
                        "提示",
                        JOptionPane.INFORMATION_MESSAGE);
            }
        });
    }

    private void addPullFileLabel() {
        pullFileLabel = new JLabel("下载文件:");
        pullFileLabel.setBounds(500, 290, 80, 25);
        pullFileLabel.setFont(font);
        this.add(pullFileLabel);
    }

    private void addPullFileButton() {
        pullFileButton = new JButton("点我下载");
        pullFileButton.setFocusPainted(false);
        pullFileButton.setFont(font);
        pullFileButton.setBounds(590, 290, 130, 25);
        pullFileButton.addActionListener(e -> {
            threadPool.execute(() -> {
                client.sendToGetFileByName();
            });
        });
        this.add(pullFileButton);
    }

    public static void main(String[] args) {
        Utils.createBaseDir();
        new ShareWareGui();
    }

}
